package dice.sinanya.dice.system;

import dice.sinanya.entity.EntityTypeMessages;
import dice.sinanya.exceptions.NotMasterException;
import dice.sinanya.start.Update;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;

import static dice.sinanya.SinaNya.runLevel;
import static dice.sinanya.system.MessagesSystem.devInfo;
import static dice.sinanya.tools.getinfo.GetMessagesProperties.entityBanProperties;
import static dice.sinanya.tools.getinfo.GetMessagesProperties.entitySystemProperties;
import static dice.sinanya.tools.getinfo.GetTime.getNowString;
import static dice.sinanya.tools.getinfo.GetTime.getTime;
import static dice.sinanya.tools.getinfo.MyDownLoadFromUrl.downloadFile;
import static dice.sinanya.tools.makedata.Sender.sender;
import static dice.sinanya.update.UpdateForDice.*;

public class DiceSystem {
    private static final Logger logger = LogManager.getLogger(DiceSystem.class.getName());
    private final EntityTypeMessages entityTypeMessages;

    public DiceSystem(EntityTypeMessages entityTypeMessages) {
        this.entityTypeMessages = entityTypeMessages;
    }

    public void update() throws NotMasterException, IOException {
        checkMaster();
        if (!checkNeedUpdate()) {
            sender(entityTypeMessages, "当前没有更新的版本");
            return;
        }
        sender(entityTypeMessages, "请注意，更新后会自动重启，需要大约20秒停机时间，请确认处于低峰时段执行此命令。如确认的话请输入.system update yes来实际执行更新");
    }

    public void updateYes() throws NotMasterException, IOException {
        checkMaster();
        if (!checkNeedUpdate()) {
            sender(entityTypeMessages, "当前没有更新的版本");
            return;
        }
        sender(entityTypeMessages, "更新开始，当前时间为:\t" + getTime(getNowString()));
        if (downUpdateZip(false)) {
            sender(entityTypeMessages, "更新成功，现在自动进行重启，重启需要约20秒，当前时间为:\t" + getTime(getNowString()));
            restart();
        } else {
            sender(entityTypeMessages, "更新失败，请重新执行.system update命令");
        }
    }

    public void updateForce() throws NotMasterException, IOException {
        checkMaster();
        if (!checkNeedWarn()) {
            sender(entityTypeMessages, "当前没有更新的预览版本");
            return;
        }
        sender(entityTypeMessages, "请注意本次更新会进入预览版线路，存在大量问题。\n如果你确认自己可以接受核心崩溃等故障，并有较高的计算机\\代码水平足以更新，请使用.system update force yes来进行更新，本次指令到此为止");
    }

    public void updateForceYes() throws NotMasterException, IOException {
        checkMaster();
        if (!checkNeedWarn()) {
            sender(entityTypeMessages, "当前没有更新的测试版本");
        }
        sender(entityTypeMessages, "更新开始。请注意本次更新会进入预览版线路，存在大量问题。\n当前时间为:\t" + getTime(getNowString()));
        if (downUpdateZip(true)) {
            sender(entityTypeMessages, "更新成功，现在自动进行重启，重启需要约20秒，当前时间为:\t" + getTime(getNowString()));
            restart();
        } else {
            sender(entityTypeMessages, "更新失败，请重新执行.system update force命令");
        }
    }

    public void restart() throws NotMasterException {
        checkMaster();
        sender(entityTypeMessages, "开始重启，需要约20秒，请耐心等待");
        switch (runLevel) {
            case CQA:
                sender(entityTypeMessages, "正在启动CQA");
                new Update().run("SinaNya.exe");
                System.exit(-1);
                break;
            case CQP:
                sender(entityTypeMessages, "正在启动CQP");
                new Update().run("SinaNya.exe");
                System.exit(-1);
                break;
            case DEBUG:
                sender(entityTypeMessages, "正在启动DEBUG");
                new Update().run("SinaNya.exe");
                System.exit(-1);
                break;
            case PDEBUG:
                sender(entityTypeMessages, "正在启动PDEBUG");
                new Update().run("SinaNya.exe");
                System.exit(-1);
                break;
            default:
                logger.info("进入default");
                sender(entityTypeMessages, "更新失败，您上次启动时的系统类型为:\t" + runLevel + "因此没有重启，可测试服务是否正常");
        }
    }

    private void checkMaster() throws NotMasterException {
        if (!entityBanProperties.getMaster().contains(entityTypeMessages.getFromQqString())) {
            throw new NotMasterException(entityTypeMessages);
        }
    }

    public boolean downUpdateZip(boolean alpha) throws IOException {
        String dir = entitySystemProperties.getSystemDir("0");

        String url = devInfo.getUpdateAddress();

        File zip = new File(URLDecoder.decode(dir, "UTF-8"), "SinaNyaNext.zip");
        File oldNext = new File(URLDecoder.decode(dir, "UTF-8"), "update");
        logger.info("systemDir:\t" + dir);
        boolean zipExists = zip.exists();
        boolean oldDirExists = oldNext.getParentFile().exists() && oldNext.getParentFile().isDirectory();
        if (zipExists) {
            zip.delete();
        }
        if (oldNext.exists()) {
            oldNext.delete();
        }

        if (!oldDirExists) {
            oldNext.getParentFile().delete();
            oldNext.getParentFile().mkdirs();
        }

        long zipSize = new URL(url + "/SinaNyaNext.zip").openConnection().getContentLength();

        downloadFile(url + "/SinaNyaNext.zip", zip, zipSize, entityTypeMessages);
        zipExists = zip.exists();


        if (oldDirExists && zipExists && zip.length() == zipSize) {
            unZip(zip, oldNext.getPath());
            return true;
        } else {
            return false;
        }
    }
}
